﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.BusinessData.MetadataModel;
using RestConnectorEntities;
using Xunit;

namespace BdcRestConnector.Tests
{
    public class BdcRestConnectorTests
    {
        private readonly IMethodInstance _miFinder;
        private readonly IMethodInstance _miSpecificFinder;

        public BdcRestConnectorTests()
        {
            // return type descriptor
            ITypeDescriptor returnTD = new MyTypeDescriptor("EmployeeList",
                "System.Collections.Generic.IEnumerable`1[System.String]",
                new MyProperties(),
                true,
                new MyTypeDescriptors(
                    new MyTypeDescriptor("Employee",
                        "RestConnectorEntities.Employee, RestConnectorEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8826b9506b6b78bc",
                        new MyProperties(),
                        false,
                        new MyTypeDescriptors(
                            new MyTypeDescriptor("EmployeeID",
                                "System.Int32",
                                new MyProperties(new KeyValuePair<string, object>("Expression", "tns:content/m:properties/d:EmployeeID")),
                                false,
                                new MyTypeDescriptors()
                            ),
                            new MyTypeDescriptor("Title",
                                "System.String",
                                new MyProperties(new KeyValuePair<string, object>("Expression", "tns:content/m:properties/d:Title")),
                                false,
                                new MyTypeDescriptors()
                            ),
                            new MyTypeDescriptor("HireDate",
                                "System.DateTime",
                                new MyProperties(new KeyValuePair<string, object>("Expression", "tns:content/m:properties/d:HireDate")),
                                false,
                                new MyTypeDescriptors()
                            )
                        )
                    )
                )
             );
            // method instance
            _miFinder = new MyMethodInstance(MethodInstanceType.Finder,
                new MyProperties(
                    new KeyValuePair<string, object>("Url", "http://adventureworks.com/AdventureWorksService.svc/Employees"),
                    new KeyValuePair<string, object>("ElementsExpression", "/tns:feed/tns:entry"),
                    new KeyValuePair<string, object>("Namespaces", "tns|http://www.w3.org/2005/Atom d|http://schemas.microsoft.com/ado/2007/08/dataservices m|http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")
                ),
                returnTD, new MyMethod(
                    new MyParameters(new MyParameter(DirectionType.Return, "employees"))
                    )
            );

            // return type descriptor
            ITypeDescriptor returnTDSpecificFinder = new MyTypeDescriptor("Employee",
                "RestConnectorEntities.Employee, RestConnectorEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8826b9506b6b78bc",
                new MyProperties(),
                false,
                new MyTypeDescriptors(
                    new MyTypeDescriptor("EmployeeID",
                        "System.Int32",
                        new MyProperties(new KeyValuePair<string, object>("Expression", "/tns:entry/tns:content/m:properties/d:EmployeeID")),
                        false,
                        new MyTypeDescriptors()
                    ),
                    new MyTypeDescriptor("Title",
                        "System.String",
                        new MyProperties(new KeyValuePair<string, object>("Expression", "/tns:entry/tns:content/m:properties/d:Title")),
                        false,
                        new MyTypeDescriptors()
                    ),
                    new MyTypeDescriptor("HireDate",
                        "System.DateTime",
                        new MyProperties(new KeyValuePair<string, object>("Expression", "/tns:entry/tns:content/m:properties/d:HireDate")),
                        false,
                        new MyTypeDescriptors()
                    )
                )
             );

            // method instance
            _miSpecificFinder = new MyMethodInstance(MethodInstanceType.SpecificFinder,
                new MyProperties(
                    new KeyValuePair<string, object>("Url", "http://adventureworks.com/AdventureWorksService.svc/Employees({employeeID})"),
                    new KeyValuePair<string, object>("Namespaces", "tns|http://www.w3.org/2005/Atom d|http://schemas.microsoft.com/ado/2007/08/dataservices m|http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")
                ),
                returnTDSpecificFinder,
                new MyMethod(new MyParameters(
                    new MyParameter(DirectionType.In, "employeeID"),
                    new MyParameter(DirectionType.Return, "employee")
                    )
                )
            );
        }


        [Fact]
        public void Finder_method_should_return_collection()
        {
            RestConnector conn = new RestConnector();
            object[] args = new object[1];
            conn.ExecuteStatic(_miFinder, new MyLobSystemInstance(), args, null);
            object returnObj = args[0];

            Assert.NotNull(returnObj);
            Assert.IsType(typeof(List<Employee>), returnObj);

            var collection = returnObj as IEnumerable<Employee>;
            Assert.NotEmpty(collection);

            var employee = collection.First();
            Assert.Equal<int>(1, employee.EmployeeID);
            Assert.Equal<string>("Production Technician - WC60", employee.Title);
            Assert.Equal<DateTime>(new DateTime(1996, 7, 31), employee.HireDate);
        }

        [Fact]
        public void Specific_finder_method_should_return_entity()
        {
            RestConnector conn = new RestConnector();
            object[] args = new object[2];
            args[0] = 1;
            conn.ExecuteStatic(_miSpecificFinder, new MyLobSystemInstance(), args, null);
            object returnObj = args[1];

            Assert.NotNull(returnObj);
            Assert.IsType(typeof(Employee), returnObj);

            var employee = returnObj as Employee;
            Assert.Equal<int>(1, employee.EmployeeID);
            Assert.Equal<string>("Production Technician - WC60", employee.Title);
            Assert.Equal<DateTime>(new DateTime(1996, 7, 31), employee.HireDate);
        }
    }








}
